热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

都会|患者_Swift两种方式实现async/await并发模型中任务超时(timeout)的取消

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Swift两种方式实现async/await并发模型中任务超时(timeout)的取消相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Swift 两种方式实现 async/await 并发模型中任务超时(timeout)的取消相关的知识,希望对你有一定的参考价值。



文章目录


  • 1. 概览
  • 2. Task 超时取消实现之思路
  • 3. 第一种实现
  • 4. 第二种实现
  • 5. 总结


1. 概览

从 Swift 5.5 开始,Apple 引入了新的 async/await 并发模型,我们可以利用它很方便的开发结构化并发代码。

在使用新的并发模型时,一个常见的需求就是任务超时的处理。

我们希望当耗时任务的执行在到达指定时间后自动取消,以免影响用户体验。

在本篇博文中,我们将用两种方法来实现新并发模型中 Task 执行的超时处理。

废话少叙,Let’s Go!!!😉




2. Task 超时取消实现之思路

在 Swift 新 async/await 并发模型中,每个 Task 都会并发执行。所以,要想实现任务超时处理我们只需要同时执行两个任务:


  1. 第一个是需要完成的任务;
  2. 第二个是超时监控任务,用它来监听第一个任务是否已超时,如果是则果断取消它;

有的小伙伴可能觉得实现监控任务有点棘手,其实,这超乎意料的简单!


3. 第一种实现

我们只需保存执行的 Task 对象,然后在超时发生时,在第二个超时监控任务中将其取消即可,代码如下:

struct TimedOutError: Error, Equatable
func execute<R>(timeout: TimeInterval, task: &#64;escaping () async throws -> R) async throws -> R

let task &#61; Task
try await task()


Task
try? await Task.sleep(until: .now &#43; .seconds(timeout), clock: .continuous)
task.cancel()


do
return try await task.value
catch
// 如果任务被取消&#xff0c;则我们知道任务超时了
if task.isCancelled
throw TimedOutError()

throw error


正如之前的实现思路&#xff0c;我们依次创建了两个任务&#xff1a;第一个是需要完成的任务&#xff0c;第二个则是超时监控任务&#xff1b;在第二个任务中&#xff0c;一旦超时到达&#xff0c;则取消第一个任务。

Task
do
let r &#61; try await execute(timeout: 3.0)
// 任务会触发超时&#xff0c;将被取消&#xff01;
try await Task.sleep(until: .now &#43; .seconds(3.1), clock: .continuous)
return 11


print("结果是 \\(r)")
catch
print("ERR: \\(error.localizedDescription)")


不过&#xff0c;这样有两个小问题&#xff1a;


  1. 如果第一个任务在超时前完成&#xff0c;超时监控任务在超时后仍会尝试取消它&#xff1b;
  2. 当任务执行出现异常时&#xff0c;我们需要判断任务是否被取消&#xff0c;然后再抛出 TimedOutError 错误&#xff1b;

虽然&#xff0c;这并不影响整个 execute() 方法的逻辑&#xff0c;但如果小伙伴们是强迫症患者&#xff0c;我们还有第二种方法可以选择。


4. 第二种实现

第二种方法和前者类似&#xff0c;不过这里我们利用了新并发模型中任务组&#xff08;TaskGroup&#xff09;的特点&#xff1a;其中所有子任务都会并发执行&#xff0c;而且我们可以取消所有子任务。

func execute2<R>(timeout: TimeInterval, task: &#64;escaping () async throws -> R) async throws -> R
try await withThrowingTaskGroup(of: R.self) group in
group.addTask
try await task()


group.addTask
try await Task.sleep(until: .now &#43; .seconds(timeout), clock: .continuous)
throw TimedOutError()


let result &#61; try await group.next()!
// 一旦我们取消所有子任务&#xff0c;则超时监控任务不会在正常任务未超时还抛出异常
group.cancelAll()
return result


如上代码所示&#xff0c;用 TaskGroup 来实现任务超时逻辑更加清晰&#xff0c;而且避免了第一种方法中的两个问题。



更多 Task 任务超时的讨论请参考下面的链接&#xff1a;

Running an async task with a timeout




5. 总结

在本篇博文中&#xff0c;我们用两种方法实现了 Swift 新 async/await 并发模型中任务超时的取消&#xff0c;任君选择。

感谢观赏&#xff0c;再会&#xff01;&#x1f60e;


推荐阅读
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • 本文探讨了Python类型注解使用率低下的原因,主要归结于历史背景和投资回报率(ROI)的考量。文章不仅分析了类型注解的实际效用,还回顾了Python类型注解的发展历程。 ... [详细]
  • Zabbix自定义监控与邮件告警配置实践
    本文详细介绍了如何在Zabbix中添加自定义监控项目,配置邮件告警功能,并解决测试告警时遇到的邮件不发送问题。 ... [详细]
  • 本文详细介绍了如何正确设置Shadowsocks公共代理,包括调整超时设置、检查系统限制、防止滥用及遵守DMCA法规等关键步骤。 ... [详细]
  • 本文介绍如何使用JavaScript中的for循环来创建一个九九乘法表,适合初学者学习循环结构的应用。 ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • 笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系& ... [详细]
  • 【MySQL】frm文件解析
    官网说明:http:dev.mysql.comdocinternalsenfrm-file-format.htmlfrm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果 ... [详细]
  • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 深入理解线程池及其基本实现
    本文探讨了线程池的概念、优势及其在Java中的应用。通过实例分析不同类型的线程池,并指导如何构建一个简易的线程池。 ... [详细]
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
author-avatar
淘气小顽童刘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有